package netmorph.model.parts;

import javax.swing.table.DefaultTableModel;

import netmorph.model.NetmorphModel;

import neuron.NetworkStatistics;

public class ElongOutputModel extends DefaultTableModel {

	static String[] params = new String[] { 
		"Basal TS Len, mean", "Basal TS Len, stdev", "Basal TS Len, error", "Basal IS Len, mean", "Basal IS Len, stdev", "Basal IS Len, error",
		"Tuft TS Len, mean", "Tuft TS Len, stdev", "Tuft TS Len, error", "Tuft IS Len, mean", "Tuft IS Len, stdev", "Tuft IS Len, error",
		"Oblique TS Len, mean", "Oblique TS Len, stdev", "Oblique TS Len, error", "Oblique IS Len, mean", "Oblique IS Len, stdev", "Oblique IS Len, error",
		};

	NetmorphModel model;
	
	String[] targets = new String[] { 
			"63", "48", "2", "21", "23", "2",
			"57", "44", "2", "47", "101", "2",
			"64", "51", "2", "27", "30", "2",
			};
	
	public double getTargetBTSLenMean() { return Double.parseDouble(targets[0]); }
	public double getTargetBTSLenStdev() { return Double.parseDouble(targets[1]); }
	public double getTargetBTSError() { return Double.parseDouble(targets[2]); }
	public double getTargetBISLenMean() { return Double.parseDouble(targets[3]); }
	public double getTargetBISLenStdev() { return Double.parseDouble(targets[4]); }
	public double getTargetBISError() { return Double.parseDouble(targets[5]); }
	
	public double getTargetTTSLenMean() { return Double.parseDouble(targets[6]); }
	public double getTargetTTSLenStdev() { return Double.parseDouble(targets[7]); }
	public double getTargetTTSError() { return Double.parseDouble(targets[8]); }
	public double getTargetTISLenMean() { return Double.parseDouble(targets[9]); }
	public double getTargetTISLenStdev() { return Double.parseDouble(targets[10]); }
	public double getTargetTISError() { return Double.parseDouble(targets[11]); }

	public double getTargetOTSLenMean() { return Double.parseDouble(targets[12]); }
	public double getTargetOTSLenStdev() { return Double.parseDouble(targets[13]); }
	public double getTargetOTSError() { return Double.parseDouble(targets[14]); }
	public double getTargetOISLenMean() { return Double.parseDouble(targets[15]); }
	public double getTargetOISLenStdev() { return Double.parseDouble(targets[16]); }
	public double getTargetOISError() { return Double.parseDouble(targets[17]); }

	public void dataChanged()
	{
		fireTableDataChanged();
	}
	
	public ElongOutputModel(NetmorphModel model) {
		this.model = model;
	}
	
	@Override
	public int getColumnCount() {
		return 3;
	}
	 
	@Override
	public int getRowCount() {
		return params.length;
	}
	
	@Override
	public String getColumnName(int column) {
		return new String[] { "Output Variable", "Current", "Target" }[column];
	}
	
	@Override
	public boolean isCellEditable(int row, int column) {
		return column==2;
	}
	
	@Override
	public Object getValueAt(int row, int column) {
		String pname = params[row]; 
		if (column == 0) { return pname; } 
		else if (column == 1) {
			NetworkStatistics stats = model.getLastStats();
			if (stats == null) return "---"; 
			switch(row) {
				case 0: return String.format("%.2f", stats.basalTermSegLenDist().mean()) + " (N=" + stats.basalTermSegLenDist().count() + ")";
				case 1: return String.format("%.2f", stats.basalTermSegLenDist().stdev());
				case 2: return String.format("%.3f", stats.basalTermSegLenDist().error(Double.parseDouble(targets[0]), Double.parseDouble(targets[1])));
				case 3: return String.format("%.2f", stats.basalIntSegLenDist().mean());
				case 4: return String.format("%.2f", stats.basalIntSegLenDist().stdev());
				case 5: return String.format("%.3f", stats.basalIntSegLenDist().error(Double.parseDouble(targets[3]), Double.parseDouble(targets[4])));

				case 6: return String.format("%.2f", stats.tuftTermSegLenDist().mean()) + " (N=" + stats.tuftTermSegLenDist().count() + ")";
				case 7: return String.format("%.2f", stats.tuftTermSegLenDist().stdev());
				case 8: return String.format("%.3f", stats.tuftTermSegLenDist().error(Double.parseDouble(targets[0]), Double.parseDouble(targets[1])));
				case 9: return String.format("%.2f", stats.tuftIntSegLenDist().mean());
				case 10: return String.format("%.2f", stats.tuftIntSegLenDist().stdev());
				case 11: return String.format("%.3f", stats.tuftIntSegLenDist().error(Double.parseDouble(targets[3]), Double.parseDouble(targets[4])));

				case 12: return String.format("%.2f", stats.obliqueTermSegLenDist().mean()) + " (N=" + stats.obliqueTermSegLenDist().count() + ")";
				case 13: return String.format("%.2f", stats.obliqueTermSegLenDist().stdev());
				case 14: return String.format("%.3f", stats.obliqueTermSegLenDist().error(Double.parseDouble(targets[0]), Double.parseDouble(targets[1])));
				case 15: return String.format("%.2f", stats.obliqueIntSegLenDist().mean());
				case 16: return String.format("%.2f", stats.obliqueIntSegLenDist().stdev());
				case 17: return String.format("%.3f", stats.obliqueIntSegLenDist().error(Double.parseDouble(targets[3]), Double.parseDouble(targets[4])));

				default: return "---";
			}
		} 
		else { 
			return targets[row]; 
		}
	}
	

	
	@Override
	public void setValueAt(Object aValue, int row, int column) {
		if (column != 2) return;
		targets[row] = (String) aValue;
	}
}
